package com.maven.user.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

/**
 * @Description:
 * =======================
 * @Author: Jovi
 * =======================
 * @Date: Created in 2020/9/25
 * =======================
 * @Version: 0.0.1
 */
public class HibernateUtil {

    private static Session session = null;

    private static final SessionFactory sessionFactory;
    /**
     * 使用threadLocal可以解决session对象的线程安全问题，使用threadlocal当一个线程调用
     * session对象的时候，threadLocal会创建一个session的副本交给该线程使用，也就是说不同的线程
     * 将使用不同的session副本来进行使用，互不影响，从而以这种方式来进行多线程
     */
    private static final ThreadLocal<Session> S_LOCAL = new ThreadLocal<>();

    static {
        try {
            // 实现hibernate的初始化
            Configuration cfg = new Configuration().configure();
            sessionFactory = cfg.buildSessionFactory();
        } catch (Throwable e) {
            System.err.println("Initial SessionFactory creation failed" + e);
            throw new ExceptionInInitializerError(e);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static Session getSession() {
        // 通过threadLocal的get方法来获得session
        session = S_LOCAL.get();
        // 第一次线程里session为空的时候，要得到一个session，并且利用threadLocal的set方法创建一个副本
        if (session == null || (session != null && session.isOpen() == false)) {

            session = sessionFactory.openSession();
            // 要添加<property name="current_session_context_class">thread</property>
            // session = sessionFactory.getCurrentSession();

            // 将session交给threadLocal来管理
            S_LOCAL.set(session);
            return session;
        }
        return session;
    }

    public static void closeSession(Session session) throws HibernateException {
        if (session != null) {
            if (session.isOpen()) {
                session.close();
            }
        }
        if (sessionFactory != null) {
            System.out.println("关闭");
            // sessionFactory.close();
        }
    }

    public static void rollback(Transaction tran) {
        try {
            if (tran != null) {
                tran.rollback();
            }
        } catch (HibernateException he) {
            System.out.println("Rollback faild." + he);
        }
    }
}
